package com.mallcai.bigdata.ladon.service.report.impl;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.mallcai.bigdata.ladon.dpl.entity.report.SqlRunLog;
import com.mallcai.bigdata.ladon.service.report.ISqlRunLogQueueService;
import com.mallcai.bigdata.ladon.service.report.ISqlRunLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.time.LocalDateTime;
import java.util.concurrent.*;

/**
 * @author feixy
 * @version 1.0
 * @date 2019-07-18 21:03
 */
@Slf4j
@Service
public class SqlRunLogQueueService implements ISqlRunLogQueueService {

    private final ExecutorService executorService = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder()
            .setDaemon(true).setNameFormat("sqlRunLogService").build());

    private final BlockingQueue<SqlRunLog> logQueue =  new ArrayBlockingQueue<>(1000);

    @Autowired
    private ISqlRunLogService iSqlRunLogService;

    @Override
    public void putLog(SqlRunLog sqlRunLog) {
        try {
            boolean offer = logQueue.offer(sqlRunLog, 1L, TimeUnit.SECONDS);
            if(!offer){
                log.warn("队列已满,当前log丢弃,{}", sqlRunLog);
            }
        } catch (InterruptedException e) {
            log.error("放置任务失败", e);
        }

    }

    @PostConstruct
    private void run(){
        executorService.execute(()->{
            LocalDateTime lastTipTime = LocalDateTime.now();
            while (true){
                try {
                    SqlRunLog  sqlRunLog = logQueue.poll(1, TimeUnit.MINUTES);
                    if(sqlRunLog != null){
                        iSqlRunLogService.insert(sqlRunLog);
                    }
                    LocalDateTime now = LocalDateTime.now();
                    if (now.isAfter(lastTipTime.plusMinutes(10))){
                        lastTipTime = now;
                        log.info("当前队列的容量为:{}", logQueue.size());
                    }
                } catch (InterruptedException e) {
                    // ignore
                    log.error("", e);
                }
            }
        });
    }

}
